package com.tdh.service;

import com.tdh.constants.Constants;
import com.tdh.dao.CkCkdxMapper;
import com.tdh.dao.CkCkxzMapper;
import com.tdh.dao.CkJzMapper;
import com.tdh.pojo.*;
import com.tdh.utils.FilesUtil;
import com.tdh.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

@Service
@Slf4j
public class CkCkdxService {

    @Autowired
    private CkCkdxMapper ckdxMapper;

    @Autowired
    private CkCkxzMapper ckxzMapper;

    @Autowired
    private CkJzMapper jzMapper;

    @Resource
    TsDmService tsDmService;

    /**
     * 查询查控对象列表
     *
     * @param zt    状态
     * @param ah    案号
     * @param mc    名称
     * @param zjhm  证件号码
     * @param start 起始行
     * @param limit 每页行数
     * @return 查控对象 List
     */
    public List<CkCkdx> queryCkdx(String[] zt, String ah, String mc, String zjhm, int start, int limit) {


        List<CkCkdx> ckdxList = ckdxMapper.queryCkdx(zt, ah, mc, zjhm, start, limit);

        //翻译代码值
        for (CkCkdx ckdx : ckdxList) {

            ckdx.setZt(tsDmService.translateZt(ckdx.getZt()));
            ckdx.setZjlx(tsDmService.translateZjlx(ckdx.getZjlx()));

            String[] ckfwArr = ckdx.getCkfw().split(",");
            StringBuilder ckfwStr = new StringBuilder();
            for(int i = 0; i < ckfwArr.length; i++) {
                ckfwStr.append(tsDmService.translateCkfw(ckfwArr[i]));
                if(i != ckfwArr.length - 1) {
                    ckfwStr.append(",");
                }
            }
            ckdx.setCkfw(ckfwStr.toString());
        }

        log.debug("查询出查控对象列表：" + ckdxList);
        return ckdxList;
    }

    /**
     * 计数符合条件的查控对象列表总行数
     *
     * @param zt   状态
     * @param ah   案号
     * @param mc   名称
     * @param zjhm 证件号码
     * @return 行数 int
     */
    public int countCkdx(String[] zt, String ah, String mc, String zjhm) {

        return ckdxMapper.countCkdx(zt, ah, mc, zjhm);
    }

    /**
     * 批量删除
     *
     * @param ids 查控对象id 流水号
     * @return 删除行数
     */
    public int deleteCkdxes(String[] ids) {

        log.debug("id: {}", Arrays.toString(ids));
        return ckdxMapper.deleteCkdxs(ids);
    }

    /**
     * 保存查控对象和查控协执对象列表
     * 新增页面，添加排序号
     * 编辑页面，根据登记批次或id列表来删除所有库中数据，添加排序号
     *
     * @param saveDTOList 前端传入对象
     * @param <T> 结果数据数据类型
     * @return Results对象
     */
    @Transactional
    public <T> Results<T> saveCkdxes(List<SaveDTO> saveDTOList) throws IOException {

        List<CkCkdx> ckdxList = new ArrayList<>();
        List<CkCkxz> ckxzList = new ArrayList<>();

        Timestamp time = new Timestamp(System.currentTimeMillis());

        // 排序号根据最大pxh自增
        int pxh = ckdxMapper.queryMaxPxh();

        for(SaveDTO saveDTO: saveDTOList) {

            //将保存对象saveDTO赋给查控对象
            CkCkdx ckdx = new CkCkdx();
            BeanUtils.copyProperties(saveDTO, ckdx);

            //设置更新时间和自增的排序号
            ckdx.setLastUpdate(time);
            ckdx.setPxh(++pxh);

            //查控范围拼接为字符串，以逗号分隔
            StringBuilder ckfw = new StringBuilder();

            //存入查控协执对象列表
            Map<String, String[]> map= saveDTO.getXzdw();

            //将每个查控对象与每个协执单位代码一一对应，存入查控协执
            for(Map.Entry<String, String[]> entry: map.entrySet()) {

                // 查控对象中协执单位类别，以逗号分隔
                ckfw.append(entry.getKey());
                ckfw.append(",");

                String[] mapValue = entry.getValue();
                for(String xzdwdm: mapValue) {

                    //将查控对象赋给查控协执对象
                    CkCkxz ckxz = new CkCkxz();
                    BeanUtils.copyProperties(ckdx, ckxz);

                    //存入表单号码、协执单位分类、协执单位代码、协执说明
                    String bdhm = StringUtil.getUUID32();
                    ckxz.setBdhm(bdhm);
                    ckxz.setXzdwfl(entry.getKey());
                    ckxz.setXzdwdm(xzdwdm);
                    ckxz.setXzsm(saveDTO.getXzsm());

                    //查控协执对象存入List
                    ckxzList.add(ckxz);
                }
            }

            //去掉最后一个逗号
            String str = ckfw.toString();
            String ckfwStr = str.substring(0, str.length() - 1);

            //设置查控范围（协执单位类别）
            ckdx.setCkfw(ckfwStr);

            //存入List
            ckdxList.add(ckdx);
        }

        int ckdxRows = 0;
        int ckxzRows = 0;
        int jzRows = 0;

        String djpc = ckdxList.get(0).getDjpc();

        //入库
        ckdxMapper.deleteByDjpc(djpc);
        ckxzMapper.deleteByDjpc(djpc);
        ckdxRows = ckdxMapper.addCkdxes(ckdxList);
        ckxzRows = ckxzMapper.addCkxzes(ckxzList);

        List<CkJz> jzList = saveDTOList.get(0).getJz();
        List<CkJz> jzs = new ArrayList<>();
        List<String> deletePath = saveDTOList.get(0).getDeleteSavedFiles();
        if(jzList != null && jzList.size() > 0) {
            int maxXh = jzMapper.queryMaxXh();
            String dateStr = StringUtil.getNowDate("yyyyMMdd");
            for(CkJz jz: jzList) {
                if(jz.getPath() != null) {

                    //文件是新增的文件，复制到存储区，设置保存后路径、序号、更新时间
                    if (!jz.getPath().startsWith(Constants.FILE_SAVE_PATH)) {
                        String tempFilePath = jz.getPath() + "\\" + jz.getWjmc();
                        String saveFilePath = Constants.FILE_SAVE_PATH + dateStr + "\\";

                        //临时文件的路径添加到待删除列表
                        deletePath.add(tempFilePath);
                        FilesUtil.copy(tempFilePath, saveFilePath);

                        jz.setPath(saveFilePath);
                        jz.setXh(++maxXh);
                        jz.setLastUpdate(time);
                    }
                    jzs.add(jz);
                }
            }
            jzMapper.deleteByDjpc(djpc);
            jzRows = jzMapper.saveJz(jzs);

            FilesUtil.deleteFile(deletePath);
        }

        if ((ckdxRows == ckdxList.size()) && (ckxzRows == ckxzList.size()) && (jzRows == jzs.size())) {
            return Results.success("保存成功");
        } else {
            return Results.error("保存查控对象失败");
        }
    }


    /**
     * 设置xml
     * @param totalNumber 总行数
     * @return Document
     */
    public Document setXML(int totalNumber) {

        Document document = DocumentHelper.createDocument();
        Element rows = document.addElement("rows");
        Element userdata = rows.addElement("userdata");
        userdata.addAttribute("name", "totalnumber");
        userdata.setText(String.valueOf(totalNumber));

        return document;
    }

    /**
     * 设置xml的行
     * @param list 填入对象List集合
     * @param totalNumber 总行数
     * @return String
     */
    public String getXml(List<CkCkdx> list, int totalNumber) {
        Document document = setXML(totalNumber);
        Element rows = document.getRootElement();

        for(CkCkdx obj: list) {
            Element row = rows.addElement("row");

            String id = obj.getCklsh();
            row.addAttribute("id", id);

            row.addElement("cell").setText("0");
            row.addElement("cell").setText(obj.getZt());

            //登记状态显示编辑按钮，非登记状态显示查看按钮
            if("登记".equals(obj.getZt())) {
                row.addElement("cell").setText("");
                row.addElement("cell").setText("../static/images/edit2.png^编辑^javascript:edit(\"" + id + "\");^_self");
            } else {
                row.addElement("cell").setText("../static/images/view2.png^查看^javascript:view(\"" + id + "\");^_self");
                row.addElement("cell").setText("");
            }

            row.addElement("cell").setText(String.valueOf(obj.getAh()));
            row.addElement("cell").setText(obj.getMc());
            row.addElement("cell").setText(obj.getZjlx());
            row.addElement("cell").setText(obj.getZjhm());
            row.addElement("cell").setText(obj.getCkfw());
            row.addElement("cell").setText(obj.getCbr());
            row.addElement("cell").setText(obj.getSjy());
        }
        return document.asXML();
    }
}
